import React, { Component } from "react";
import moment from "moment";
import { DragDropContext } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";
import _ from "lodash";
import Card from "../DayCard/index";
import {
  MONTH_TBALE_COL,
  MONTH_TBALE_ROW,
  WEEKS
} from "../../constants/constant";

import { MoveType } from "../../constants/constant";
import {
  todayHasEvent,
  sortAndSupplementEvent,
  getCalendarStart
} from "../../util/util";

import "./index.scss";

// 日历的主体部分
@DragDropContext(HTML5Backend)
export default class Calendar extends Component {
  constructor(props) {
    super(props);
    this.renderDays = this.renderDays.bind(this);
    this.renderHeader = this.renderHeader.bind(this);
    this.changeEvent = this.changeEvent.bind(this);
    this.changeActiveEventId = this.changeActiveEventId.bind(this);
    this.state = {
      moveOption: {
        moveType: MoveType.NEW_EVENT
      },

      // 初始化活动列表
      events: this.props.events,

      // 当前操作的事件Id
      activeEventId: 0
    };
  }

  // 更改活动对象
  changeEvent(moveOption, modifiedEvent) {
    if (!modifiedEvent) {
      this.setState({
        moveOption
      });
    }

    if (moveOption.moveType !== MoveType.NEW_EVENT || modifiedEvent.id) {
      this.setState({
        moveOption,
        events: this.state.events.map(event => {
          if (event.id === modifiedEvent.id) {
            return Object.assign({}, event, modifiedEvent);
          }
          return event;
        })
      });
    } else {
      const id = _.maxBy(this.state.events, "id").id + 1;
      this.setState({
        activeEventId: id,
        moveOption,
        events: this.state.events.concat({
          id,
          ...modifiedEvent
        })
      });
    }
  }

  // 修改当前活动对象
  changeActiveEventId(id) {
    this.setState({
      activeEventId: id
    });
  }

  renderHeader() {
    return (
      <div className="rc_calendar-header">
        {moment.weekdaysShort().map((item, index) => {
          return (
            <div className="rc_calendar-header_week" key={index}>
              {item}
            </div>
          );
        })}
      </div>
    );
  }

  renderDays() {
    let tempMap = new Map();
    const {
      currentDate,
      onDragNewEnd,
      onEventContextMenu,
      eventTooltip,
      canDrag,
      canDrop
    } = this.props;
    const start = getCalendarStart(currentDate);

    return (
      <div className="rc_calendar-body">
        {Array.from(new Array(MONTH_TBALE_ROW * MONTH_TBALE_COL)).map(
          (item, index) => {
            const date = moment(start).add(index, "d");
            // 周内第一天重新排序
            if (date.day() === 0) {
              tempMap.clear();
            }
            const events = sortAndSupplementEvent(
              this.state.events.reduce((array, event, index) => {
                const result = todayHasEvent(event.begin, event.end, date);

                if (result > 0) {
                  const tempEvent = {
                    ...event,
                    isStart: result === 2 || result === 4,
                    isEnd: result === 3 || result === 4
                  };
                  array.push(tempEvent);
                }
                return array;
              }, []),
              date,
              tempMap
            );

            let classNames = [];
            if (index < 7) {
              classNames.push("rc_card_first-row");
            }
            if (index > 34) {
              classNames.push("rc_card_last-row");
            }
            if (index % 7 === 0) {
              classNames.push("rc_card_first-col");
            }
            if (index % 7 === 6) {
              classNames.push("rc_card_last-col");
            }

            return (
              <Card
                className={classNames.join(" ")}
                key={index}
                date={date}
                today={date.valueOf() === this.props.nowDate.valueOf()}
                moveOption={this.state.moveOption}
                events={events}
                activeEventId={this.state.activeEventId}
                changeEvent={this.changeEvent}
                changeActiveEventId={this.changeActiveEventId}
                allEvents={this.state.events}
                onDragNewEnd={onDragNewEnd}
                onEventContextMenu={onEventContextMenu}
                eventTooltip={eventTooltip}
                canDrag={canDrag}
                canDrop={canDrop}
              />
            );
          }
        )}
      </div>
    );
  }

  render() {
    const { className } = this.props;
    return (
      <div className={`rc_calendar`}>
        {this.renderHeader()}
        {this.renderDays()}
      </div>
    );
  }
}
